<?php
namespace app\common\model\order;

use app\common\model\CartModel;
use app\common\model\delivery\DeliveryTpl;
use app\common\model\goods\GoodsModel;
use app\common\model\redis\RedisLock;
use app\common\model\UserAddressModel;
use think\Db;
use think\Exception;
use think\Model;

/**
 * 商品订单模型
 * User: LK
 * Date: 2021/3/24
 */
class OrderModel extends Model
{
    protected $name = 'order';

    protected static $status = ['0','1','2','3','4','5'];

    /**
     * 确认订单
     *
     * @param int $user_id 用户ID
     * @param string $use_type 使用位置:mini=小程序,pc=PC
     * @param int $user_address_id 用户地址ID
     * @param int $user_coupon_id 优惠券ID
     *
     * @param object $goods_params 商品信息
     *
     * @param int $goods_id 商品ID
     * @param int $goods_spec_id 规格ID
     * @param int $num 数量
     *
     * @param string $cart_ids 购物车ID集
     *
     * @param string $dispatch_type 发货方式:express=物流快递,ziti=自提
     */
    public function confirmOrder($params,$user_id,$type)
    {
        extract($params);

        try {
            switch ($type){
                case 'goods':
                    $params_goods = [
                        [
                            'goods_id' => $goods_id,
                            'goods_spec_id' => $goods_spec_id,
                            'num' => $num,
                        ]
                    ];
                    break;
                case 'cart':
                    $params_goods = CartModel::field(['goods_id','goods_spec_id','num'])
                        ->where(['id' => ['in', $cart_ids]])
                        ->select();
                    if(!$params_goods){
                        throw new Exception('未找到购物车中相关商品信息', 43001);
                    }
                    $params_goods = collection($params_goods)->toArray();
                    break;
                case 'json':
                    foreach ($goods_params as $key => $val){
                        if(!array_key_exists('goods_id',$val) || !array_key_exists('goods_spec_id',$val) || !array_key_exists('num',$val)){
                            throw new Exception('参数错误', 40001);
                        }
                        if(empty($val['goods_id']) || empty($val['goods_spec_id']) || empty($val['num'])){
                            throw new Exception('参数错误', 40001);
                        }
                    }
                    $params_goods = $goods_params;
                    break;
            }

            $returnData = [];

            // 获取商品信息
            $goods_list = [];// 结算商品
            $goods_num = 0;// 商品总数
            $goods_weight = 0;// 商品总重
            $all_goods_price = 0;// 商品总额
            $order_price = 0;// 订单总额
            $coupon_price = 0;// 优惠金额
            $delivery_price = 0;// 运费

            // 获取地址信息
            $user_address = UserAddressModel::theDefault($user_id, $user_address_id);

            // 配送方式
            $dispatch_data = [
                [
                    'id' => 0,
                    'value' => 'express',
                    'name' => '物流快递',
                    'disabled' => false,
                ],
                [
                    'id' => 1,
                    'value' => 'ziti',
                    'name' => '自提',
                    'disabled' => false,
                ],
            ];

            foreach ($params_goods as $key => $value)
            {

                $goods = GoodsModel::get($value['goods_id'],['spec1' => function($query) use ($value){
                    $query->where('goods_spec_id', $value['goods_spec_id']);
                }]);

//                if($goods->is_index == 1) {
//                    // 未核销完兑换券无法下单
//                    $user_coupon_exchange_count_0 = model('app\common\model\UserCouponExchangeModel')
//                        ->where(['user_id' => $user_id,'status' => 1])
//                        ->count();
//                    if($user_coupon_exchange_count_0 > 0) {
//                        throw new Exception('请核销结束后再下单', 43008);
//                    }
//                }

                $goods_list[] = $goods;

                if(!$goods){
                    throw new Exception('未找到购物车中相关商品信息', 43001);
                }
                if(!empty($goods->deletetime)){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43002);
                }
                if($goods->status != 'up'){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43003);
                }
                if(!$goods->spec1){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43004);
                }
                if(!empty($goods->spec1->deletetime)){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]已被下架", 43005);
                }
                if($goods->spec1->status != 1){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]已被下架", 43006);
                }
                if($goods->spec1->spec_stock < $value['num']){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]商品规格库存不足", 43007);
                }

                // 商品信息
                $params_goods[$key]['goods_name'] = $goods->goods_name;
                $params_goods[$key]['image'] = ImageAddDomain( !empty($goods->spec1->spec_image)?$goods->spec1->spec_image:$goods->image );
                $params_goods[$key]['goods_spec_str'] = $goods->spec1->spec_item_value;
                $spec_price = $goods->spec1->spec_price;
                $params_goods[$key]['goods_price'] = $spec_price;
                $params_goods[$key]['all_goods_price'] = $spec_price * $value['num'];
                $params_goods[$key]['coupon_price'] = 0;

                // 计算运费
                $params_goods[$key]['delivery_price'] = 0.00;
                if(!empty($user_address) && $dispatch_type == 'express'){
                    $params_goods[$key]['delivery_price'] = DeliveryTpl::deliveryPrice($goods->dispatch_ids, $user_address, $value['num'], $goods->spec1->weight);
                    // 商品运费累计
                    $delivery_price += $params_goods[$key]['delivery_price'];
                }

                // 订单商品总数
                $goods_num += $value['num'];
                // 订单商品总重
                $goods_weight += $goods->spec1->weight;
                // 统计商品ID集
                $goods_ids[] = $value['goods_id'];

                $all_goods_price += $params_goods[$key]['all_goods_price'];

                // 发货方式统计
                $goods_dispatch_type = explode(',',$goods->dispatch_type);
                if(!in_array('express', $goods_dispatch_type)) {
                    $dispatch_data[0]['disabled'] = true;
                }
                if(!in_array('ziti', $goods_dispatch_type)) {
                    $dispatch_data[1]['disabled'] = true;
                }

            }

            $order_price = $all_goods_price;

            // 获取可用优惠券列表: 1.匹配下单中的单个商品符合条件的优惠券,2.匹配包含下单中全部商品的优惠券
            $coupon_list = \app\common\model\UserCouponModel::UsableCoupon($user_id, $order_price, $use_type, $goods_ids, $user_coupon_id);

            // 判断是否可使用优惠券并且获取优惠金额
            if ($user_coupon_id) {
                $coupon_price = \app\common\model\UserCouponModel::CouponInfo($user_id, $order_price, $user_coupon_id);
                $order_price = $order_price - $coupon_price;
            }

            // 运费不统计在优惠规则里
            $order_price += $delivery_price;

            $returnData['dispatch_data'] = $dispatch_data;
            $returnData['user_address'] = $user_address;
            $returnData['goods'] = $params_goods;
            $returnData['coupon_list'] = $coupon_list;
            $returnData['all_goods_price'] = $all_goods_price;
            $returnData['coupon_price'] = $coupon_price;
            $returnData['delivery_price'] = $delivery_price;
            $returnData['order_price'] = $order_price;

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => $returnData
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 下单
     *
     * @param int $user_id 用户ID
     *
     * @param string $place_type 下单类型:goods=单商品,cart=购物车
     * @param string $use_type 平台:pc=PC,mini=微信小程序,app=App
     * @param string $remark 买家备注
     * @param int $user_address_id 用户地址ID
     * @param int $user_coupon_id 优惠券ID
     * @param string $dispatch_type 发货方式:express=物流快递,ziti=自提
     * @param int $coupon_exchange_id 兑换活动ID
     *
     * $place_type = goods
     * @param int $goods_id 商品ID
     * @param int $goods_spec_id 规格ID
     * @param int $num 数量
     *
     * $place_type = cart
     * @param string $cart_ids 购物车ID集
     */
    public function placeOrder($params,$user_id)
    {
        extract($params);

        // 下单锁
        $redis_key = 'userPlaceOrder'.$user_id;

        Db::startTrans();
        try {
            $user = model('app\common\model\User')->get($user_id);
            if($user->group_id > 1) {
//                throw new Exception('非用户身份无法下单', 43106);
            }

            if(!RedisLock::lock($redis_key)){
                throw new Exception('系统繁忙,请稍后再试', 40002);
            }

            switch ($place_type){
                case 'goods':
                    if(!$goods_id || !$goods_spec_id || !$num){
                        throw new Exception('参数错误', 40001);
                    }
                    $params_goods = [
                        [
                            'goods_id' => $goods_id,
                            'goods_spec_id' => $goods_spec_id,
                            'num' => $num,
                        ]
                    ];
                    break;
                case 'cart':
                    if(!$cart_ids){
                        throw new Exception('参数错误', 40001);
                    }
                    $params_goods = CartModel::field(['goods_id','goods_spec_id','num'])
                        ->where(['id' => ['in', $cart_ids]])
                        ->select();
                    if(!$params_goods){
                        throw new Exception('未找到购物车中相关商品信息', 43001);
                    }
                    $params_goods = collection($params_goods)->toArray();
                    break;
                case 'json':
                    foreach ($goods_params as $key => $val){
                        if(!array_key_exists('goods_id',$val) || !array_key_exists('goods_spec_id',$val) || !array_key_exists('num',$val)){
                            throw new Exception('参数错误', 40001);
                        }
                        if(empty($val['goods_id']) || empty($val['goods_spec_id']) || empty($val['num'])){
                            throw new Exception('参数错误', 40001);
                        }
                    }
                    $params_goods = $goods_params;
                    break;
            }

            // 获取地址信息
            $user_address = UserAddressModel::theDefault($user_id, $user_address_id);
            if(!$user_address && $dispatch_type == 'express'){
                throw new Exception('请选择地址', 43101);
            }

            // 获取商品信息
            $goods_num = 0;// 商品总数
            $goods_weight = 0;// 商品总重
            $all_goods_price = 0;// 商品总额
            $order_price = 0;// 订单总额
            $coupon_price = 0;// 优惠金额
            $delivery_price = 0;// 运费

            // 下单扣库存,未支付回滚数据
            $queueGoodsParams = [];

            foreach ($params_goods as $key => $value)
            {
                $goods = GoodsModel::get($value['goods_id'],['spec1' => function($query) use ($value){
                    $query->where('goods_spec_id', $value['goods_spec_id']);
                }]);

                $goods_list[] = $goods;

                if(!$goods){
                    throw new Exception('未找到购物车中相关商品信息', 43001);
                }
                if(!empty($goods->deletetime)){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43002);
                }
                if($goods->status != 'up'){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43003);
                }
                if(!$goods->spec1){
                    throw new Exception("商品[ $goods->goods_name ]已被下架", 43004);
                }
                if(!empty($goods->spec1->deletetime)){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]已被下架", 43005);
                }
                if($goods->spec1->status != 1){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]已被下架", 43006);
                }
                if($goods->spec1->spec_stock < $value['num']){
                    throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]商品规格库存不足", 43007);
                }
                // 爆款产品兑换活动校验
//                if($goods->is_index == 1) {
//                    if(empty($coupon_exchange_id)) {
//                        throw new Exception("请选择兑换活动", 43008);
//                    }else{
//                        // 未核销完兑换券无法下单
//                        $user_coupon_exchange_count_0 = model('app\common\model\UserCouponExchangeModel')
//                            ->where(['user_id' => $user_id,'status' => 1])
//                            ->count();
//                        if($user_coupon_exchange_count_0 > 0) {
//                            throw new Exception('请核销结束后再下单', 43107);
//                        }
//                        if($value['num'] > 1) {
//                            throw new Exception('本产品限购1份', 43108);
//                        }
//                    }
//                }
                $goods_dispatch_type = explode(',',$goods->dispatch_type);
                if(!in_array($dispatch_type, $goods_dispatch_type)) {
                    switch ($dispatch_type) {
                        case 'express':
                            throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]暂不支持物流快递", 43105);
                            break;
                        case 'ziti':
                            throw new Exception("商品[ " .$goods->goods_name . $goods->spec1->spec_item_value ." ]暂不支持自提", 43105);
                            break;
                    }
                }

                // 库存扣减方式:place=拍下减库存,pay=付款减库存
                // 下单扣库存
                if($goods->stock_type == 'place'){
                    GoodsModel::updateStock($value['goods_id'],$value['goods_spec_id'],$value['num']);
                    $queueGoodsParams[] = [
                        'goods_id' => $value['goods_id'],
                        'goods_spec_id' => $value['goods_spec_id'],
                        'num' => $value['num']
                    ];
                }

                // 商品信息
                $params_goods[$key]['goods_name'] = $goods->goods_name;
                $params_goods[$key]['image'] = ImageAddDomain( !empty($goods->spec1->spec_image)?$goods->spec1->spec_image:$goods->image );
                $params_goods[$key]['goods_spec_str'] = $goods->spec1->spec_item_value;
                $spec_price = $goods->spec1->spec_price;
                $params_goods[$key]['goods_price'] = $spec_price;
                $params_goods[$key]['all_goods_price'] = $spec_price * $value['num'];
                $params_goods[$key]['coupon_price'] = 0;
                $params_goods[$key]['is_burst_order'] = $goods->is_index;

                // 计算运费
                $params_goods[$key]['delivery_price'] = 0;
                if($dispatch_type == 'express') {
                    if(!empty($user_address)){
                        $params_goods[$key]['delivery_price'] = DeliveryTpl::deliveryPrice($goods->dispatch_ids, $user_address, $value['num'], $goods->spec1->weight);
                        // 商品运费累计
                        $delivery_price += $params_goods[$key]['delivery_price'];
                    }
                }

                // 订单商品总数
                $goods_num += $value['num'];
                // 订单商品总重
                $goods_weight += $goods->spec1->weight;
                // 统计商品ID集
                $goods_ids[] = $value['goods_id'];

                $all_goods_price += $params_goods[$key]['all_goods_price'];
            }

            $order_price = $all_goods_price;

            // 判断是否可使用优惠券并且获取优惠金额
            if ($user_coupon_id) {
                $coupon_price = \app\common\model\UserCouponModel::CouponInfo($user_id, $order_price, $user_coupon_id);
                $order_price = $order_price - $coupon_price;
            }

            // 按照金额占比分配优惠金额, 方便后续售后
            if($coupon_price > 0){
                // 单款商品优惠总金额 = 单款商品总额 / 优惠前订单总额 * 优惠的金额
                foreach ($params_goods as $k => $v)
                {
                    $params_goods[$k]['coupon_price'] = $v['all_goods_price'] / $all_goods_price * $coupon_price;
                }
            }

            // 运费不统计在优惠规则里
            $order_price += $delivery_price;

            // 订单金额不准为0
            if($order_price <= 0){
                throw new Exception("订单金额不准为0", 43102);
            }

            //++ 查找绑定上级店铺/公司 ++//
//            $shop_id = 0;
//            $user_relation = model('app\common\model\UserRelationModel')->get(['user_id' => $user_id]);
//            if($user_relation->user_id_2 > 0) {
//                $shop_id = $user_relation->user_id_2;
//            }else{
//                if($user_relation->user_id_3 > 0) {
//                    $shop_id = $user_relation->user_id_3;
//                }
//            }
            //-- 查找绑定上级店铺/公司 --//

            // 拆单
            $new_params_goods = [];
            foreach ($params_goods as $val) {
//                if($val['is_burst_order'] == 1 && $shop_id == 0) {
//                    throw new Exception("暂未绑定店铺,无法下单", 43104);
//                }
                $new_params_goods[$val['is_burst_order']][] = $val;
            }

            // 创建订单
            // 唯一订单号
            $uniqueOrderNo = UniqueOrderNo();
            $uniqueArray = [
                'user_id' => $user_id,
                'unique_order_no' => $uniqueOrderNo,
                'trade_no' => $uniqueOrderNo,
                'delivery_price' => $delivery_price,
                'coupon_price' => $coupon_price,
                'order_price' => $order_price,
                'need_price' => $order_price,
                'coupon_id' => $user_coupon_id,
                'is_pay' => 0,
                'createtime' => time(),
            ];
            $uniqueOrder = OrderUniqueModel::create($uniqueArray);

            foreach ($new_params_goods as $item_key => $item) {
                $order_no = OrderNo();
                $order = [
                    'unique_order_no' => $uniqueOrderNo,
                    'dispatch_type' => $dispatch_type,
//                    'shop_id' => $shop_id,
                    'user_id' => $user_id,
                    'order_no' => $order_no,
                    //'coupon_id' => $user_coupon_id,
                    'is_pay' => 0,
                    'pay_order_no' => $uniqueOrderNo,
                    'is_close' => 0,
                    'status' => 0,
                    'contact' => $user_address['name']??'',
                    'mobile' => $user_address['mobile']??'',
                    'province' => $user_address['province']??'',
                    'city' => $user_address['city']??'',
                    'area' => $user_address['area']??'',
                    'address' => $user_address['detail']??'',
                    'remark' => $remark,
                    //'goods_num' => $goods_num,
                    'platform' => $use_type,
                    'is_burst_order' => $item_key,
//                    'coupon_exchange_id' => $coupon_exchange_id,
                    'createtime' => time(),
                    'delivery_price' => 0,
                    'goods_price' => 0,
                    'coupon_price' => 0,
                    'order_price' => 0,
                    'total_fee' => 0,
                    'goods_num' => 0,
                ];

                $order_goods = [];
                foreach ($item as $val){
                    $order_goods_item = [
                        'order_no' => $order_no,
                        'user_id' => $user_id,
                        //'order_id' => $order_res->id,
                        'goods_id' => $val['goods_id'],
                        'goods_spec_id' => $val['goods_spec_id'],
                        'goods_name' => $val['goods_name'],
                        'num' => $val['num'],
                        'image' => $val['image'],
                        'goods_spec_str' => $val['goods_spec_str'],
                        'price' => $val['goods_price'],
                        'total_price' => $val['all_goods_price'],
                        'delivery_price' => $val['delivery_price'],
                        'coupon_price' => $val['coupon_price'],
                        'total_fee' => $val['all_goods_price'] + $val['delivery_price'] - $val['coupon_price'],
                        'createtime' => time(),
                    ];

                    $order['delivery_price'] += $order_goods_item['delivery_price'];
                    $order['goods_price'] += $order_goods_item['total_price'];
                    $order['coupon_price'] += $order_goods_item['coupon_price'];
                    $order['order_price'] += $order_goods_item['total_fee'];
                    $order['total_fee'] += $order_goods_item['total_fee'];
                    $order['goods_num'] += $order_goods_item['num'];

                    $order_goods[] = $order_goods_item;
                }

                $order_res = $this->create($order);
                if(!$order_res){
                    throw new Exception("下单失败", 43103);
                }
                $order['id'] = $order_res->id;

                foreach ($order_goods as $key => $val) {
                    $order_goods[$key]['order_id'] = $order['id'];
                }

                model('app\common\model\order\OrderGoodsModel')->insertAll($order_goods);
                $oper = [
                    'id' => $user_id,
                ];
                OrderAction::operAdd($order, null, $oper, 'user', '订单创建成功');

            }

            //改变优惠券使用状态
            if ($user_coupon_id != 0) {
                \app\common\model\UserCouponModel::where(['id' => $user_coupon_id])->update(['status' => 2, 'usetime' => time()]);
            }

            //删除购物车
            if (!empty($cart_ids)) {
                CartModel::where(['id' => ['in', $cart_ids], 'user_id' => $user_id])->update(['deletetime' => time()]);
            }

            // TODO 下单后操作
            // 发布任务队列
            // 消息参数
            $queueParams = [
                'order_id' => $uniqueOrder->id,
                'user_coupon_id' => $user_coupon_id,
                'goods' => $queueGoodsParams
            ];
            // 延时执行时间(秒)
//            $queueTime = model('common/Config')->where(['name' => 'pay_close_time'])->value('value') * 60;
            $queueTime = model('app\common\model\SystemModel')->where('id',1)->value('order_pay_close_time') * 60;
            $queue = 'jrbq';
            // 下单后未支付自动关闭订单操作
            Queue('app\common\job\OrderAfterAutoOper@NoPayAutoCloseOrderOper', $queueParams, $queueTime, $queue);

            $returnData = [
                'amount' => $order_price,
                'order_no' => $uniqueOrderNo,
                'pay_close_time' => time() + $queueTime,
            ];

            RedisLock::unlock($redis_key);
            Db::commit();
            return [
                'code' => 200,
                'msg' => '下单成功',
                'data' => $returnData
            ];
        }catch (\Exception $e) {
            RedisLock::unlock($redis_key);
            Db::rollback();
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 订单列表
     *
     * @param int $user_id 用户ID
     * @param int $status 订单状态:0=全部,1=待支付,2=待收货,3=已完成(0=待支付,1=待发货,2=待收货,3=已完成,4=已完成,5=已取消)
     * @param int $page 页码
     * @param int $limit 每页数据
     * @param string $search
     */
    public function getOrderPageList($params,$user_id)
    {
        extract($params);

        try {
            $field = [
                'id as order_id','order_no','unique_order_no','order_price','total_fee','goods_num','createtime','status','claim_code','claim_code_image','dispatch_type'
            ];
            $where = [
                'user_id' => $user_id,
//                'is_sales' => 0,
//                'is_close' => 0,
            ];

            if (!empty($search)){
                if(is_numeric($search)){
                    $where['order_no'] = ['like',"%$search%"];
                }else{
                    $order_ids = OrderGoodsModel::where([
                            'user_id' => $user_id,
                            'goods_name' => ['like',"%$search%"],
                        ])->column('order_id');
                    $where['id'] = ['in',$order_ids];
                }
            }

            //0=全部,1=待支付,2=待收货,3=已完成(0=待支付,1=待发货,2=待收货,3=已完成,4=已完成,5=已取消)
            switch ($status){
                case 0:
                    break;
                case 1:
                    $where['status'] = 0;
                    break;
                case 2:
                    $where['status'] = ['in',[1,2]];
                    break;
                case 3:
//                    $where['status'] = 3;
                    $where['status'] = ['in',[3,4]];
                    break;
//                case 4:
//                    $where['status'] = ['in',[3,4]];
////                    $where['status'] = 4;
//                    break;
            }
            $list = $this
                ->with(['item'=>function($query){
                    $query->field(['id','order_id','goods_id','goods_name','goods_spec_str','image','price','num','total_price','total_fee','is_sales','refund_status']);
                }])
                ->field($field)
                ->where($where)
                ->whereNull('deletetime')
                ->order('createtime','desc')
                ->paginate($limit, false, ['page' => $page]);

            foreach ($list as $row){
                $row->claim_code_image = full_url($row->claim_code_image);
                $row->pay_close_time = 0;
                if($row->status == 0){
//                    $queueTime = model('common/Config')->where(['name' => 'pay_close_time'])->value('value') * 60;
                    $queueTime = model('app\common\model\SystemModel')->where('id',1)->value('order_pay_close_time') * 60;
                    $row->pay_close_time = $row->createtime + $queueTime;
                }
                $row->createtime = datetime($row->createtime);
                foreach ($row->item as $row2){
                    $row2->image = ImageAddDomain($row2->image);
                }

                // 获取主订单支付价格,用来在支付页显示 2022-11-30 16:05:06
                $row->amount = $row->order_price;
                $orderUnique = OrderUniqueModel::get(['unique_order_no' => $row->unique_order_no]);
                if($orderUnique){
                    $row->amount = $orderUnique->need_price;
                }

                // 按钮状态:0=不显示,1=显示
                $btn = [
                    'is_pay' => 0,//支付按钮
                    'is_cancel' => 0,//取消按钮
                    'is_received' => 0,//收货按钮
                    'is_express' => 0,//查看物流
                ];

                switch ($row->status){
                    case 0:
                        $btn['is_pay'] = 1;
                        $btn['is_cancel'] = 1;
                        break;
                    case 1:
                        break;
                    case 2:
                        if($row->dispatch_type == 'express') {
                            $btn['is_received'] = 1;
                            $btn['is_express'] = 1;
                        }
                        break;
                    case 3:
                    case 4:
                        break;
                }

                $row->btn = $btn;
            }
            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => $list
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 订单详情
     *
     * @param int $order_id 订单ID
     */
    public function getOrderDetail($params, $user_id)
    {
        extract($params);

        try {
            $field = [
                'id as order_id','order_no','unique_order_no','goods_price','order_price','total_fee','delivery_price','coupon_price','goods_num','contact','mobile','province','city','area','address','remark','status','createtime','pay_time','received_time','pay_type','is_sales','dispatch_type','claim_code','claim_code_image'
            ];
            $where = [
                'id' => $order_id
            ];

            $data = $this
                ->with(['item'=>function($query){
                    $query->field(['id','order_id','goods_id','goods_spec_id','goods_name','goods_spec_str','image','price','num','total_price','total_fee','is_sales','refund_status']);
                }])
                ->field($field)
                ->where($where)
                ->find();
            $data->claim_code_image = full_url($data->claim_code_image);
            $pay_close_time = model('app\common\model\SystemModel')->where('id',1)->value('order_pay_close_time') * 60;
            $data->pay_close_time = $data->createtime + $pay_close_time;
            $data->createtime = datetime($data->createtime);
            $data->pay_time = datetime($data->pay_time);
            $data->received_time = datetime($data->received_time);

            $data->amount = $data->order_price;
            $orderUnique = OrderUniqueModel::get(['unique_order_no' => $data->unique_order_no]);
            if($orderUnique){
                // 获取主订单支付价格,用来在支付页显示 2022-11-30 16:05:06
                $data->amount = $orderUnique->need_price;
            }

            // 按钮状态:0=不显示,1=显示
            $btn1 = [
                'is_pay' => 0,//支付按钮
                'is_cancel' => 0,//取消按钮
                'is_received' => 0,//收货按钮
                'is_express' => 0,//查看物流
            ];
            // 订单状态:0=全部,1=待支付,3=待收货,4=已完成(0=待支付,1=待发货,2=待收货,3=待评论,4=已完成,5=已取消)
            switch ($data->status) {
                case 0:
                    $btn1['is_pay'] = 1;
                    $btn1['is_cancel'] = 1;
                    break;
                case 1:
                    break;
                case 2:
                    if($data->dispatch_type == 'express') {
                        $btn1['is_express'] = 1;
                        $btn1['is_received'] = 1;
                    }
                    break;
                case 3:
                case 4:
                    if($data->dispatch_type == 'express') {
                        $btn1['is_express'] = 1;
                    }
                    break;
            }
            $data->btn = $btn1;
            $btn2 = [
                'is_sales' => 0,//售后按钮
            ];
            foreach ($data->item as $row2) {
                $row2->image = ImageAddDomain($row2->image);
                if ($data->status > 0 && $data->status != 5 && $row2->is_sales == 0) {
                    $btn2['is_sales'] = 1;
                }
                $row2->btn = $btn2;
            }

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => $data
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 取消订单
     *
     * @param int $order_id 订单ID
     */
    public function CancelOrder($params,$user_id)
    {
        extract($params);

        try {
            $data = $this->get($order_id);
            if(!$data){
                throw new \Exception('未找到订单',45001);
            }
            if($data->status != 0){
                throw new \Exception('订单状态错误',45002);
            }
            if($data->is_close != 0){
                throw new \Exception('订单已关闭',45003);
            }
            $data->status = 5;
            $data->is_close = 1;
            $data->cancel_time = time();
            $data->close_time = time();
            $data->save();

            $oper = [
                'id' => $user_id,
            ];
            // 库存回滚
            $orderGoods = OrderGoodsModel::where(['id' => $order_id])->select();
            foreach ($orderGoods as $row){
                $goods = GoodsModel::get($row->goods_id);
                if($goods->stock_type == 'place'){
                    GoodsModel::stockRollback($row->goods_id,$row->goods_spec_id,$row->num);
                }
            }
            // 退回优惠券
            if($data->coupon_id > 0){
                \app\common\model\UserCouponModel::where(['id' => $data->coupon_id])->update(['status' => 1, 'usetime' => '']);
                OrderAction::operAdd($data, null, $oper, 'user', '订单取消恢复优惠券');
            }
            OrderAction::operAdd($data, null, $oper, 'user', '用户取消订单');

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => []
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 确认收货
     *
     * @param int $order_id 订单ID
     */
    public function confirmReceipt($params, $user_id)
    {
        extract($params);

        try {
            $data = $this->get($order_id);
            if(!$data){
                throw new \Exception('未找到订单',45101);
            }
            if($data->status != 2){
                throw new \Exception('订单状态错误',45102);
            }
            $data->status = 3;
            $data->received_time = time();
            $data->save();

            $oper = [
                'id' => $user_id,
            ];
            OrderAction::operAdd($data, null, $oper, 'user', '用户确认收货');

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => []
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 售后申请信息
     *
     * @param int $user_id 用户ID
     * @param int $order_id 订单ID
     * @param int $order_goods_id 订单商品ID
     */
    public function applyRefundInfo($params, $user_id)
    {
        extract($params);

        try {
            $order = $this->get($order_id);
            if (!$order) {
                throw new \Exception('未找到订单',45201);
            }
            if ($order->is_close == 1) {
                throw new \Exception('订单已关闭',45203);
            }
            if ($order->is_sales == 1) {
                throw new \Exception('订单状态错误',45202);
            }
            if ($order->status == 0 || $order->status == 5) {
                throw new \Exception('订单状态错误',45202);
            }
            $field = [
                'id as order_goods_id','order_id','goods_name','goods_spec_str','image',
                'price','num','total_price','delivery_price','coupon_price','total_fee','is_sales'
            ];
            $order_goods = OrderGoodsModel::field($field)->where(['id' => $order_goods_id])->find();
            if (!$order_goods) {
                throw new \Exception('未找到订单商品',45204);
            }
            if($order_goods->is_sales > 0){
                throw new \Exception('操作失败商品售后已申请',45205);
            }
            $order_goods->image = ImageAddDomain($order_goods->image);

//            $refund_reason = RefundReason::all();
//
//            $returnData['order_goods'] = $order_goods;
//            $returnData['refund_reason'] = $refund_reason;

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => $order_goods
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 售后申请
     *
     * @param int $user_id 用户ID
     * @param int $type 售后类型:1=退款,2=退货退款
     * @param int $order_id 订单ID
     * @param int $order_goods_id 订单商品ID
     * @param int $num 售后数量
     * @param string $refund_price 退款金额
     * @param string $cause 售后原因
    //     * @param string $content 售后描述
     * @param string $images 图片集
     */
    public function applyRefund($params, $user_id)
    {
        extract($params);

        Db::startTrans();
        try {
            // 售后锁
            $redis_key = 'applyRefundOrder'.$order_goods_id;
            if(!RedisLock::lock($redis_key)){
                throw new Exception('系统繁忙,请稍后再试', 40002);
            }
            $order = $this->get($order_id);
            if (!$order) {
                throw new Exception('未找到订单',45301);
            }
            if ($order->is_close == 1) {
                throw new Exception('订单已关闭',45303);
            }
            if ($order->is_sales == 1) {
                throw new Exception('订单状态错误',45302);
            }
            if ($order->status == 0 || $order->status == 5) {
                throw new Exception('订单状态错误',45302);
            }
            $order_goods = OrderGoodsModel::get($order_goods_id);
            if (!$order_goods) {
                throw new Exception('未找到订单商品',45304);
            }
            if($order_goods->is_sales != 0){
                throw new Exception('操作失败商品售后已申请',45305);
            }

            if( round((($order_goods->total_fee / $order_goods->num) * $num),2) != $refund_price){
                throw new Exception('退款价格错误',45305);
            }
            $refund_no = OrderNo();
            $refundModel = OrderRefundModel::create([
                'refund_no' => $refund_no,
                'order_no' => $order->order_no,
                'user_id' => $user_id,
                'order_id' => $order_goods->order_id,
                'order_goods_id' => $order_goods->id,
                'goods_id' => $order_goods->goods_id,
                'goods_spec_id' => $order_goods->goods_spec_id,
                'num' => $num,
                'pay_price' => $order_goods->total_fee,
                'refund_price' => $refund_price,
                'cause' => $cause,
//                'content' => $content,
                'images' => $images,
                'mold' => $type,
                'status' => 0,
                'createtime' => time(),
                'image' => $order_goods->image,
                'goods_name' => $order_goods->goods_name,
                'goods_spec_str' => $order_goods->goods_spec_str,
            ]);
            $is_sales = 2;
            $order_goods_sales = OrderGoodsModel::where(['order_id' => $order_id, 'id' => ['<>',$order_goods_id]])->field('id,is_sales')->select();
            $order_goods_sales_count = 0;
            foreach ($order_goods_sales as $row)
            {
                if($row->is_sales > 0){
                    $order_goods_sales_count += 1;
                }
            }
            if($order_goods_sales_count == count($order_goods_sales)){
                $is_sales = 1;
            }
            $order->is_sales = $is_sales;
            $order->save();

            $order_goods->is_sales = $type;
            $order_goods->refund_no = $refund_no;
            $order_goods->refund_status = 0;
            $order_goods->save();

            $order->aftersale_status = 0;
            $oper = [
                'id' => $user_id,
            ];
            OrderAction::operAdd($order, null, $oper, 'user', '用户申请售后');

            RedisLock::unlock($redis_key);
            Db::commit();
            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => []
            ];
        }catch (Exception $e) {
            RedisLock::unlock($redis_key);
            Db::rollback();
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 删除订单
     *
     * @param int $order_id 订单ID
     */
    public function deleteOrder($params, $user_id)
    {
        extract($params);

        try {
            $data = $this->get($order_id);
            if(!$data){
                throw new \Exception('未找到订单',45001);
            }
            $data->deletetime = time();
            $data->save();

            $oper = [
                'id' => $user_id,
            ];
            OrderAction::operAdd($data, null, $oper, 'user', '用户删除订单');

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => []
            ];
        }catch (\Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }

    /**
     * 订单状态角标数量
     * @ApiMethod GET
     * @param int $user_id
     */
    public function getOrderStatusNum($user_id)
    {
        try {
            $where = [
                'user_id' => $user_id,
                'is_close' => 0,
            ];
            $data = [
                // 待付款
                'noPay' => $this->where($where)->where(['status' => 0])->whereNull('deletetime')->count(),
                // 待收货
                'noSendDelivery' => $this->where($where)->where(['status' => ['in',[1,2]]])->whereNull('deletetime')->count(),
                // 已完成
                'finished' => $this->where($where)->where(['status' => ['in',[3,4]]])->whereNull('deletetime')->count(),
            ];

            return [
                'code' => 200,
                'msg' => '请求成功',
                'data' => $data
            ];
        }catch (Exception $e) {
            return [
                'code' => $e->getCode(),
                'msg' => $e->getMessage(),
                'data' => $e->getLine()
            ];
        }
    }


    public function item()
    {
        return $this->hasMany('app\common\model\order\OrderGoodsModel', 'order_id', 'order_id');
    }
}